import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn import svm

# 浅层机器学习
# 读取excel指定列的数据
def read_column_from_excel(file_path, sheet_name, column_name):
    """
    此函数从Excel文件中读取指定的列。

    参数:
    file_path (str): Excel文件的路径。
    sheet_name (str): 工作表的名称。
    column_name (str): 列的名称。

    返回:
    pandas.Series: 从Excel文件中读取的列。
    """
    # Load the Excel file
    df = pd.read_excel(file_path, sheet_name=sheet_name)

    # Return the specified column
    return df[column_name].tolist()


class WinePredictor:
    def __init__(self, file_path, sheet_name):
        self.file_path = file_path
        self.sheet_name = sheet_name
        self.rf = RandomForestClassifier(random_state=42)
        self.clf = svm.SVC(random_state=42, probability=True)
        self.sc = StandardScaler()

    def read_column_from_excel(self, column_name):
        df = pd.read_excel(self.file_path, sheet_name=self.sheet_name)
        return df[column_name].tolist()

    def train(self):
        listA = []
        listB = []
        for i in range(1, 8):
            listA.append(self.read_column_from_excel('A' + str(i)))
        arrA = np.insert(listA, 0, 1, axis=1)
        for i in range(17, 26):
            listB.append(self.read_column_from_excel('F' + str(i)))
        arrB = np.insert(listB, 0, 0, axis=1)
        arrC = np.concatenate((arrA, arrB), axis=0)
        X = arrC[:, 1:162]
        y = arrC[:, 0]
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
        self.sc.fit(X_train)
        X_train_std = self.sc.transform(X_train)
        X_test_std = self.sc.transform(X_test)
        self.rf.fit(X_train_std, y_train)
        self.clf.fit(X_train_std, y_train)
        # print('Random Forest Accuracy: %.2f' % self.rf.score(X_test_std, y_test))
        # print('SVM Accuracy: %.2f' % self.clf.score(X_test_std, y_test))

    # def predict(self, X):
    #     X_std = self.sc.transform(X)
    #     rf_pred = self.rf.predict(X_std)
    #     clf_pred = self.clf.predict(X_std)
    #     return rf_pred, clf_pred
    def predict(self, X):
        X_std = self.sc.transform(X)
        rf_pred = self.rf.predict(X_std)
        clf_pred = self.clf.predict(X_std)
        rf_proba = self.rf.predict_proba(X_std)
        clf_proba = self.clf.predict_proba(X_std)
        dist_to_boundary = self.clf.decision_function(X_std)

        print('随机森林预测结果（1：七年年限，0：10年年限）： ', rf_pred)
        print('随机森林预测概率（第一项表示接近0的概率，第二项表示接近1的概率） ', rf_proba)
        print('支持向量机预测结果（1：七年年限，0：10年年限） ', clf_pred)
        print('支持向量机预测概率（第一项表示接近0的概率，第二项表示接近1的概率） ', clf_proba)
        print('支持向量机决策边界距离: ', dist_to_boundary)
        return rf_pred, clf_pred, rf_proba, clf_proba,dist_to_boundary


# 引用这个训练的模型
predictor = WinePredictor(r'紫外光谱扫描数据_向量_年份顺序.xlsx', 'Sheet1')
predictor.train()
# 对数据进行预测，可以随意更改读取的数据内容
data = np.array(read_column_from_excel(r'紫外光谱扫描数据_向量_年份顺序.xlsx', 'Sheet1', 'E16'))
dataA = data.reshape(1, -1)
# print(dataA)
rf_pred, clf_pred, rf_proba, clf_proba, dist_to_boundary = predictor.predict(dataA)
# print(rf_pred)
# print(clf_pred)
